package red;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * BigDecimal帮助类
 *
 * @author yuqianag
 * @create 2018/05/17
 **/
public final class BigDecimalUtil {
    private static Logger logger = LoggerFactory.getLogger(BigDecimalUtil.class);

    /**
     * 将string转换为BigDecimal.如果 target为空，则返回0
     *
     * @param target
     * @return
     */
    public static BigDecimal parse(String target) {
        if (StringUtils.isEmpty(target)) {
            return new BigDecimal(0);
        }

        try {
            return new BigDecimal(target);
        } catch (Exception e) {
            logger.error("parse error:" + e.getMessage(), e);
            return new BigDecimal(0);
        }
    }

    /**
     * 将BigDecimal转换为BigDecimal. 如果target为null，则返回0
     * @param target
     * @return
     */
    public static BigDecimal parse(BigDecimal target) {
        if (null == target) {
            return new BigDecimal(0);
        }

        return target;
    }
    
    /**
     * LIUB
     * double 相加
     *
     * @param d1
     * @param d2
     * @return
     */
    public static double sum(double d1, double d2) {
      BigDecimal bd1 = new BigDecimal(Double.toString(d1));
      BigDecimal bd2 = new BigDecimal(Double.toString(d2));
      return bd1.add(bd2).doubleValue();
    }

    /**
     * LIUB
     * double 相减
     *
     * @param d1
     * @param d2
     * @return
     */
    public static double sub(double d1, double d2) {
      BigDecimal bd1 = new BigDecimal(Double.toString(d1));
      BigDecimal bd2 = new BigDecimal(Double.toString(d2));
      return bd1.subtract(bd2).doubleValue();
    }
    
    /**
     * LIUB
     * double 乘法
     *
     * @param d1
     * @param d2
     * @return
     */
    public static double mul(double d1, double d2) {
      BigDecimal bd1 = new BigDecimal(Double.toString(d1));
      BigDecimal bd2 = new BigDecimal(Double.toString(d2));
      return bd1.multiply(bd2).doubleValue();
    }
    
    /**
     * LIUB
     * double 相减
     *
     * @param d1
     * @param d2
     * @return
     */
    public static BigDecimal sub(BigDecimal d1, BigDecimal d2) {
    	if(d1 != null && d2 != null){
    		return d1.subtract(d2);
        }
        return null;
    }
    
    /**
     * LIUB
     * double 相加
     *
     * @param d1
     * @param d2
     * @return
     */
    public static BigDecimal sum(BigDecimal d1, BigDecimal d2) {
    	if(d1 != null && d2 != null){
      	  return d1.add(d2);
        }
      return null;
    }
    
    /**
     * LIUB
     * double 乘法
     *
     * @param d1
     * @param d2
     * @return
     */
    public static BigDecimal mul(BigDecimal d1, BigDecimal d2) {
      if(d1 != null && d2 != null){
    	  return d1.multiply(d2) ;
      }
      return null;
    }
    
    public static BigDecimal mul(double d1, BigDecimal d2) {
    	if(d2 != null){
    		BigDecimal bd1 = new BigDecimal(Double.toString(d1));
    		return bd1.multiply(d2);
    	}
        return null ;
      }
    
    
    /**
     * LIUB
     * double 除法
     *
     * @param d1
     * @param d2
     * @param scale 四舍五入 小数点位数
     * @return
     */
    public static BigDecimal div(BigDecimal d1, BigDecimal d2, int scale) {
      //  当然在此之前，你要判断分母是否为0，
      //  为0你可以根据实际需求做相应的处理
		if(d1 != null && d2 != null){
	  	  return d1.divide(d2, scale, BigDecimal.ROUND_HALF_UP);
	    }
		return null;
    }

    /**
     * LIUB
     * double除法
     * @param d1
     * @param d2
     * @param scale
     * @param round
     * @return
     */
    public static BigDecimal div(BigDecimal d1, BigDecimal d2, int scale,int round) {
    	if(d1 != null && d2 != null){
  	  	  return d1.divide(d2, scale, round);
  	    }
      return null;
    }
    
    /**
     * LIUB
     * double 除法
     *
     * @param d1
     * @param d2
     * @param scale 四舍五入 小数点位数
     * @return
     */
    public static double div(double d1, double d2, int scale) {
      //  当然在此之前，你要判断分母是否为0，
      //  为0你可以根据实际需求做相应的处理
      BigDecimal bd1 = new BigDecimal(Double.toString(d1));
      BigDecimal bd2 = new BigDecimal(Double.toString(d2));
      return bd1.divide(bd2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }
    
    /**
     * LIUB
     * double除法
     * @param d1
     * @param d2
     * @param scale
     * @param round
     * @return
     */
    public static double div(double d1, double d2, int scale,int round) {
      BigDecimal bd1 = new BigDecimal(Double.toString(d1));
      BigDecimal bd2 = new BigDecimal(Double.toString(d2));
      return bd1.divide(bd2, scale, round).doubleValue();
    }

    
    /**
     * LIUB
     * 8位小数
     * @param num
     * @return
     */
    public static boolean isNumber(BigDecimal num){
    		if(num == null) return false;
    		Pattern pattern=Pattern.compile("^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,8})?$");
    		Matcher match=pattern.matcher(num.toPlainString());   
    	    return match.matches();
    }
    
    /**
     * LIUB
     * 2位小数
     * @param num
     * @return
     */
    public static boolean isNumberOftwo(BigDecimal num){
		if(num == null) return false;
		Pattern pattern=Pattern.compile("^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?$");
		Matcher match=pattern.matcher(num.toString());   
	    return match.matches();
}
    
    /**
     * 生成随机红包
     * @param n
     * @param money
     * @param multiPower
     * @param deci
     * @return
     */
    public static double[] allocateRedPkg(int n, double money,int deci) {
    		double multiPower = 100000000d;
    		if(deci==2) multiPower = 100d;
    		double minMoney = BigDecimalUtil.mul(n,BigDecimalUtil.div(1d, multiPower, deci));
    		if(minMoney>money) return null; //表示金额太小
    		money = BigDecimalUtil.mul(money, multiPower);
		double[]  result = new double[n];
		double[] randNumber = new double[n];
		double randSum = 0d;   //随机数和
		double allocateSum = BigDecimalUtil.sub(money,Double.parseDouble(n+""));    //扣除每人最低分配金额后再分配
		for (int i = 0; i < randNumber.length; i++) {
			randNumber[i]=BigDecimalUtil.mul(Math.random(),allocateSum);    //生成随机数
			randSum = BigDecimalUtil.sum(randSum, randNumber[i]);
		}
		double left = allocateSum;
		for (int i = 0; i < result.length-1; i++) {			
			result[i] = Math.round(BigDecimalUtil.mul(BigDecimalUtil.div(randNumber[i],randSum,deci), allocateSum));
			left = BigDecimalUtil.sub(left,result[i]);
			result[i] = BigDecimalUtil.div(BigDecimalUtil.sum(result[i],1), multiPower,deci);//把最低金额加回去
		}
		result[n-1] = BigDecimalUtil.div(BigDecimalUtil.sum(left,1),multiPower,deci,BigDecimal.ROUND_DOWN);
		return result;
	}
    
    /**
     * 求和
     * @param ems
     * @return
     */
    public static double sum(double[] ems){
    		double total = 0d;
    		for(double em:ems){
    			total = BigDecimalUtil.sum(total, em);
    		}
    		return total;
    }
    
    public static void main(String[] args) {
    		Boolean tre = BigDecimalUtil.isNumber(new BigDecimal("0.00000001"));
    		System.out.println(tre);
    		
    		
    		double mul = BigDecimalUtil.mul(100000000.00000001, 100000000);
    		System.out.println(mul);
    		
    		BigDecimal bd = new BigDecimal("100000000.00000001");
    		BigDecimal bd1 = new BigDecimal("100000000");
    		
    		System.out.println(bd.multiply(bd1).toBigInteger());
    		
    		
	}
	
	
    
    
    
    
}
